/**
 * @file dvc_supercap.cpp
 * @author yssickjgd (yssickjgd@mail.ustc.edu.cn)
 * @brief 超级电容
 * @version 0.1
 * @date 2022-08-13
 *
 * @copyright USTC-RoboWalker (c) 2022
 *
 */

/* Includes ------------------------------------------------------------------*/

#include "dvc_supercap.h"

/* Private macros ------------------------------------------------------------*/

/* Private types -------------------------------------------------------------*/

/* Private variables ---------------------------------------------------------*/

/* Private function declarations ---------------------------------------------*/

/* Function prototypes -------------------------------------------------------*/

/**
 * @brief 初始化超级电容通信, 切记__CAN_ID避开0x201~0x20b, 默认收包CAN1的0x210, 滤波器最后一个, 发包CAN1的0x220
 *
 * @param __hcan 绑定的CAN总线
 * @param __CAN_ID 收数据绑定的CAN ID
 * @param __Limit_Power_Max 最大限制功率, 0表示不限制
 */
void Class_Supercap::Init(CAN_HandleTypeDef *__hcan, uint16_t __CAN_ID, float __Limit_Power_Max)
{
    hcan = __hcan;
    CAN_ID = __CAN_ID;
    Limit_Power_Max = __Limit_Power_Max;

    //如果改变CAN总线或CAN_ID, 这里的代码需要适当改写
    CAN_Filter_Mask_Config(&hcan1, CAN_FILTER(13) | CAN_FIFO_0 | CAN_FIFO_1 | CAN_STDID | CAN_DATA_TYPE, CAN_ID, 0x3FF);
    CAN_Tx_Data = CAN1_0x220_Tx_Data;
}

/**
 * @brief 获取存储的能量
 *
 * @return float 存储的能量
 */
float Class_Supercap::Get_Stored_Energy()
{
    return (Stored_Energy);
}

/**
 * @brief 获取输出的功率
 *
 * @return float 输出的功率
 */
float Class_Supercap::Get_Output_Power()
{
    return (Output_Power);
}

/**
 * @brief 设定绝对最大限制功率
 *
 * @param __Limit_Power 绝对最大限制功率
 */
void Class_Supercap::Set_Limit_Power(float __Limit_Power)
{
    Limit_Power = __Limit_Power;
}

/**
 * @brief CAN通信接收回调函数
 *
 * @param Rx_Data 接收的数据
 */
void Class_Supercap::CAN_RxCpltCallback(uint8_t *Rx_Data)
{
    Stored_Energy = (int16_t)(Rx_Data[0] << 8 | Rx_Data[1]);
    Output_Power = (float)(Rx_Data[2] << 8 | Rx_Data[3]) / 100.0f;
}

/**
 * @brief 定时器发包回调函数
 *
 */
void Class_Supercap::TIM_Send_PeriodElapsedCallback()
{
    if (Limit_Power < 0)
    {
        Limit_Power = 0;
    }
    if (Limit_Power_Max != 0 && Limit_Power > Limit_Power_Max)
    {
        Limit_Power = Limit_Power_Max;
    }
    
    CAN_Tx_Data[0] = (int16_t)Limit_Power >> 8;
    CAN_Tx_Data[1] = (int16_t)Limit_Power;
}

/************************ COPYRIGHT(C) USTC-ROBOWALKER **************************/
